﻿using System;
using System.Configuration;
using System.Reflection;
using ERP.Framework.Components.Utilities.TracingHelper;

namespace ERP.Framework.Components.Utilities.TypeHelper
{
    /// <summary>
    /// Dynamic objects creation
    /// </summary>
    public sealed class TypeFactory
    {
        #region Methods

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <param name="typeName">Name of the type.</param>
        /// <returns></returns>
        public static object CreateInstance(string typeName)
        {
            object instance = null;
            TraceUtil.Write("TypeFactory::CreateInstance", "Dynamically loading type '{0}'", new object[] { typeName });
            try
            {
                TypeInfo typeInfo = new TypeInfo(typeName);
                instance = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(typeInfo.AssemblyName, typeInfo.Name);
            }
            catch (ConfigurationException)
            {
                throw;
            }
            catch (Exception inner)
            {
                string msg = string.Format("Failed to dynamically load assembly '{0}'", typeName);
                TraceUtil.Write("TypeFactory::CreateInstance", "Throwing ConfigurationException: [{0}]", new object[] { msg });
                throw new ConfigurationException(msg, inner);
            }
            return instance;
        }

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <param name="typeName">Name of the type.</param>
        /// <param name="args">The args.</param>
        /// <returns></returns>
        public static object CreateInstance(string typeName, params object[] args)
        {
            TypeInfo typeInfo = null;
            object instance = null;
            string msg = null;
            try
            {
                typeInfo = new TypeInfo(typeName);
                Type type = Assembly.Load(typeInfo.AssemblyName).GetType(typeInfo.Name);
                if (type != null)
                {
                    instance = Activator.CreateInstance(type, args);
                }
            }
            catch (ConfigurationException)
            {
                throw;
            }
            catch (Exception inner)
            {
                msg = string.Format("Failed to dynamically load assembly '{0}'", typeName);
                TraceUtil.Write("TypeFactory::CreateInstance", "Throwing ConfigurationException: [{0}]", new object[] { msg });
                throw new ConfigurationException(msg, inner);
            }
            return instance;
        }

        #endregion

    }
}
